﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using Microsoft.Win32;
using System.Windows;
using System.Xml;
using System.IO;

namespace SHomeWorkshop.LunarMind.Commands
{
    /// <summary>
    /// 打开文档命令。此命令总是可以运行的。
    /// </summary>
    public static class OpenDocumentCommand
    {
        private static RoutedUICommand routedUICmd;//创建私有字段

        public static RoutedUICommand RoutedUICmd//创建只读静态属性
        {
            get { return routedUICmd; }
        }

        static OpenDocumentCommand()//类型构造器
        {
            routedUICmd = new RoutedUICommand(
                "OpenDocumentCommand",
                "OpenDocumentCommand",
                typeof(OpenDocumentCommand),//创建RoutedUICommand对象
                null);

            //未知原因的故障，可能与焦点有关。改由MainWindows_PreviewKeyDown事件实现。
            //new InputGestureCollection() 
            //    { 
            //        new KeyGesture(Key.O,ModifierKeys.Control,"Ctrl+O")
            //    }

            cmdBinding.Command = routedUICmd;
            cmdBinding.CanExecute += new CanExecuteRoutedEventHandler(cmdBinding_CanExecute);
            cmdBinding.Executed += new ExecutedRoutedEventHandler(cmdBinding_Executed);
        }

        private static CommandBinding cmdBinding = new CommandBinding();

        public static CommandBinding CmdBinding
        {
            get { return cmdBinding; }
        }

        static void cmdBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            OpenDocument();
        }

        internal static void OpenDocument()
        {
            if (Globals.MainWindow.IsModified)
            {
                MessageBoxResult result = MessageBox.Show("当前文档已被修改，是否需要保存？",
                    Globals.AppName, MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);
                switch (result)
                {
                    case MessageBoxResult.Yes:
                        {
                            if (SaveDocumentCommand.SaveDocument() != true) return;

                            break;
                        }
                    case MessageBoxResult.No:
                        {
                            break;
                        }
                    case MessageBoxResult.Cancel:
                        {
                            return;
                        }
                    default: break;
                }
            }

            ReadDocument();
        }

        internal static bool ReadDocument()
        {
            if (Globals.cmdParameterString != null)
            {
                if (ReadDocumentFromDiskFile(Globals.cmdParameterString) == false)
                {
                    Globals.MainWindow.InitilizeDocument();

                    //尝试根标题居中
                    Globals.MainWindow.TryToScrollRootTitleAtCenter();

                    Globals.cmdParameterString = null;
                    //文件不存在（这种情况极罕见，通常都是用户手工从命令行调用才会发生）。
                    return false;
                }

                RecentFileItem.WriteRecentFilesToXmlFile(Globals.cmdParameterString);
                RecentFileItem.ReadRecentFilesFromXmlFile();

                Globals.MainWindow.Activate();

                Globals.cmdParameterString = null;//这个只在程序启动时执行一次。
                return true;
            }

            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = Globals.AppName + "——打开文档：";
            ofd.Filter = Globals.AppName + " 思维导图文档(*.lunarmind)|*.lunarmind|Png 导出图(*.png)|*.png";
            ofd.FilterIndex = 0;
            ofd.Multiselect = false;

            if (ofd.ShowDialog() != true) return false;

            if (ofd.FileName.EndsWith(".png"))
            {
                //本程序导出的png格式的图片末尾附带了整个文档的Xml数据。
                if (ReadOutportedPNGImageFile(ofd.FileName))
                {
                    Globals.MainWindow.RefreshTitleAndLinesLocation();
                    Globals.MainWindow.IsModified = false;
                    Globals.MainWindow.FullPathOfDiskFile = ofd.FileName;
                }
                else return false;
            }
            else
            {
                if (ReadDocumentFromDiskFile(ofd.FileName))
                {
                    Globals.MainWindow.RefreshTitleAndLinesLocation();
                    Globals.MainWindow.IsModified = false;
                    Globals.MainWindow.FullPathOfDiskFile = ofd.FileName;
                }
                else return false;
            }

            Globals.MainWindow.TryToScrollRootTitleAtCenter();

            RecentFileItem.WriteRecentFilesToXmlFile(ofd.FileName);
            RecentFileItem.ReadRecentFilesFromXmlFile();

            return true;
        }

        internal static bool ReadOutportedPNGImageFile(string filename)
        {
            XmlReader reader = null;
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ConformanceLevel = ConformanceLevel.Document;
            settings.IgnoreWhitespace = true;
            settings.IgnoreComments = true;
            reader = XmlReader.Create(/*"file:///" +加这个会出错！！*/ filename, settings);

            Globals.MainWindow.MainXmlDocument.RemoveAll();

            bool start = false;
            StringBuilder sb = new StringBuilder();
            using (StreamReader sr = File.OpenText(filename))
            {
                string s = "";
                while ((s = sr.ReadLine()) != null)
                {
                    if (start == false)
                    {
                        if (s.EndsWith("<?Lunar Mind?>"))
                        {
                            start = true;
                        }

                        continue;
                    }

                    sb.Append(s);
                }

                if (sb.Length <= 0)
                {
                    MessageBox.Show("这个PNG文件可能不是由本程序导出的图片文件！无法从中获取文档内容。",
                        Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return false;
                }

                Globals.MainWindow.MainXmlDocument.LoadXml(sb.ToString());
                Globals.MainWindow.BuildTitlesAndLines();
                Globals.MainWindow.RefreshTitleAndLinesLocation();
                Globals.MainWindow.FullPathOfDiskFile = filename;
                Globals.MainWindow.IsModified = false;

                //打开文档后，必须调用此方法。
                Globals.MainWindow.ReNullRootTitle();

                Globals.MainWindow.TryToScrollRootTitleAtCenter();

                return true;
            }
        }

        internal static bool ReadDocumentFromDiskFile(string fullFilePath)
        {
            if (fullFilePath == null || fullFilePath.Length <= 0 || System.IO.File.Exists(fullFilePath) != true) return false;

            if (File.Exists(fullFilePath) == false) return false;

            if (fullFilePath.ToLower().EndsWith(".png"))
            {
                Commands.OpenDocumentCommand.ReadOutportedPNGImageFile(fullFilePath);

                RecentFileItem.WriteRecentFilesToXmlFile(fullFilePath);
                RecentFileItem.ReadRecentFilesFromXmlFile();
                return true;
            }

            try
            {
                using (System.Xml.XmlReader reader = new System.Xml.XmlTextReader(/*"file:///" +加这个会出错！！*/ fullFilePath))
                {
                    Globals.MainWindow.MainXmlDocument.Load(reader);

                    if (Globals.MainWindow.MainXmlDocument == null ||
                        Globals.MainWindow.MainXmlDocument.DocumentElement == null ||
                        Globals.MainWindow.MainXmlDocument.DocumentElement.Name != "Doc")
                    {
                        MessageBox.Show("这个文件可能不是由本程序生成的文件！无法从中获取文档内容。",
                            Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                        return false;
                    }

                    if (Globals.MainWindow.MainXmlDocument.DocumentElement.SelectSingleNode("TitleSet") == null)
                    {
                        MessageBox.Show("这个文件可能不是由本程序生成的文件！无法从中获取文档内容。",
                            Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                        return false;
                    }

                    Globals.MainWindow.BuildTitlesAndLines();
                    Globals.MainWindow.RefreshTitleAndLinesLocation();
                    Globals.MainWindow.IsModified = false;
                    Globals.MainWindow.FullPathOfDiskFile = fullFilePath;
                }

                //打开文档后，必须调用此方法。
                Globals.MainWindow.ReNullRootTitle();

                Globals.MainWindow.TryToScrollRootTitleAtCenter();
                return true;
            }
            catch (Exception ex)
            {
                Dialogs.LunarMsgBox.MsgBoxShow(Globals.AppName,
                    "读取文件时发生意外。异常信息如下：\r\n", ex.Message,
                    ex.StackTrace, MessageBoxButton.OK, MessageBoxImage.Warning,
                    null, MessageBoxResult.OK, Globals.MainWindow);
                return false;
            }
        }

        static void cmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;//打开文档，此命令总是有效。
        }
    }
}
